package top.idcard.agent.biz.rw.read.device;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xvolks.jnative.JNative;
import org.xvolks.jnative.Type;
import org.xvolks.jnative.exceptions.NativeException;
import org.xvolks.jnative.pointers.Pointer;
import org.xvolks.jnative.pointers.memory.MemoryBlockFactory;
import top.idcard.agent.biz.entity.Certification;

import java.io.Closeable;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

public class CVRNativeFunction implements Closeable {

    private Logger logger = LoggerFactory.getLogger(CVRNativeFunction.class);

    public Integer init() {
        JNative aNative = null;
        int result = FunctionResultEnum.FAILED.getCode();
        for (int port = 1001; port < 1024; port++) {
            try {
                aNative = new JNative("Termb.dll", DeviceInterfaceConstant.CVR_InitComm);
                aNative.setRetVal(Type.INT); // 指定返回参数的类型
                aNative.setParameter(0, port);
                aNative.invoke(); // 调用方法
                logger.info("尝试连接到端口：" + port);
                result = Integer.parseInt(aNative.getRetVal());
                if (result == FunctionResultEnum.SUCCESS.getCode() || result == FunctionResultEnum.INIT_REPEAT_OPTION.getCode()) {
                    break;
                }
            } catch (IllegalAccessException e) {
                logger.error("本地方法调用时出错", e);
            } catch (NativeException e) {
                logger.error("加载动态库时出错", e);
            }
        }
        return result;
    }

    public Integer auth() {
        JNative aNative = null;
        int result = FunctionResultEnum.FAILED.getCode();
        try {
            aNative = new JNative("Termb.dll", DeviceInterfaceConstant.CVR_Authenticate);
            aNative.invoke();
            result = Integer.parseInt(aNative.getRetVal());
        } catch (IllegalAccessException e) {
            logger.error("本地方法调用时出错", e);
        } catch (NativeException e) {
            logger.error("加载动态库时出错", e);
        }
        return result;
    }

    public Integer getStatus(){
        JNative aNative = null;
        int result = FunctionResultEnum.STATUS_NOT_CONNECTED.getCode();
        try {
            aNative = new JNative("Termb.dll", DeviceInterfaceConstant.CVR_GetStatus);
            aNative.invoke();
            result = Integer.parseInt(aNative.getRetVal());
        } catch (IllegalAccessException e) {
            logger.error("本地方法调用时出错", e);
        } catch (NativeException e) {
            logger.error("加载动态库时出错", e);
        }
        return result;
    }


    public Certification.CertificationEnum getCertType() {
        JNative aNative = null;
        Integer certType = null;
        try {
            aNative = new JNative("Termb.dll", DeviceInterfaceConstant.GetCertType);
            aNative.setRetVal(Type.INT); // 指定返回参数的类型
            Pointer rsP = new Pointer(MemoryBlockFactory.createMemoryBlock(4 * 30));
            Pointer lengthP = new Pointer(MemoryBlockFactory.createMemoryBlock(4 * 10));
            aNative.setParameter(0, rsP);
            aNative.setParameter(1, lengthP);
            aNative.invoke();
            int rtv = Integer.parseInt(aNative.getRetVal());
            if (rtv == FunctionResultEnum.SUCCESS.getCode()) {
                int len = lengthP.getAsInt(0);
                byte[] resultBytes = new byte[len];
                resultBytes = rsP.getMemory();
                certType = rsP.getAsInt(0);
            }
            rsP.dispose();
            lengthP.dispose();
        } catch (IllegalAccessException e) {
            logger.error("本地方法调用时出错", e);
        } catch (NativeException e) {
            logger.error("加载动态库时出错", e);
        }
        return Certification.CertificationEnum.valueOf(certType);
    }

    public String getPeopleName() {
        JNative aNative = null;
        String name = null;
        try {
            aNative = new JNative("Termb.dll", DeviceInterfaceConstant.GetPeopleName);
            aNative.setRetVal(Type.INT); // 指定返回参数的类型
            Pointer rsP = new Pointer(MemoryBlockFactory.createMemoryBlock(120));
            Pointer lengthP = new Pointer(MemoryBlockFactory.createMemoryBlock(4 * 10));
            aNative.setParameter(0, rsP);
            aNative.setParameter(1, lengthP);
            aNative.invoke();
            int rtv = Integer.parseInt(aNative.getRetVal());
            if (rtv == FunctionResultEnum.SUCCESS.getCode()) {
                int len = lengthP.getAsInt(0);
                byte[] resultBytes = new byte[len];
                resultBytes = rsP.getMemory();
                try {
                    name = new String(resultBytes, "gb2312");
                } catch (UnsupportedEncodingException ex) {
                    logger.error("编码结果时异常", ex);
                }
            }
            rsP.dispose();
            lengthP.dispose();
        } catch (IllegalAccessException e) {
            logger.error("本地方法调用时出错", e);
        } catch (NativeException e) {
            logger.error("加载动态库时出错", e);
        }
        return name;
    }

    public Short getPeopleSex() {
        JNative aNative = null;
        Short sex = null;
        try {
            aNative = new JNative("Termb.dll", DeviceInterfaceConstant.GetPeopleSex);
            aNative.setRetVal(Type.INT); // 指定返回参数的类型
            Pointer rsP = new Pointer(MemoryBlockFactory.createMemoryBlock(2));
            Pointer lengthP = new Pointer(MemoryBlockFactory.createMemoryBlock(4 * 10));
            aNative.setParameter(0, rsP);
            aNative.setParameter(1, lengthP);
            aNative.invoke();
            int rtv = Integer.parseInt(aNative.getRetVal());
            if (rtv == FunctionResultEnum.SUCCESS.getCode()) {
                int len = lengthP.getAsInt(0);
                byte[] resultBytes = new byte[len];
                resultBytes = rsP.getMemory();
                try {
                    sex = Short.valueOf(new String(resultBytes, "gb2312"));
                } catch (UnsupportedEncodingException ex) {
                    logger.error("编码结果时异常", ex);
                }
            }
            rsP.dispose();
            lengthP.dispose();
        } catch (IllegalAccessException e) {
            logger.error("本地方法调用时出错", e);
        } catch (NativeException e) {
            logger.error("加载动态库时出错", e);
        }
        return sex;
    }

    public String getPeopleNation() {
        JNative aNative = null;
        String name = null;
        try {
            aNative = new JNative("Termb.dll", DeviceInterfaceConstant.GetPeopleNation);
            aNative.setRetVal(Type.INT); // 指定返回参数的类型
            Pointer rsP = new Pointer(MemoryBlockFactory.createMemoryBlock(20));
            Pointer lengthP = new Pointer(MemoryBlockFactory.createMemoryBlock(4 * 10));
            aNative.setParameter(0, rsP);
            aNative.setParameter(1, lengthP);
            aNative.invoke();
            int rtv = Integer.parseInt(aNative.getRetVal());
            if (rtv == FunctionResultEnum.SUCCESS.getCode()) {
                int len = lengthP.getAsInt(0);
                byte[] resultBytes = new byte[len];
                resultBytes = rsP.getMemory();
                try {
                    name = new String(resultBytes, "gb2312");
                } catch (UnsupportedEncodingException ex) {
                    logger.error("编码结果时异常", ex);
                }
            }
            rsP.dispose();
            lengthP.dispose();
        } catch (IllegalAccessException e) {
            logger.error("本地方法调用时出错", e);
        } catch (NativeException e) {
            logger.error("加载动态库时出错", e);
        }
        return name;
    }

    public String getPeopleBirthday() {
        JNative aNative = null;
        String name = null;
        try {
            aNative = new JNative("Termb.dll", DeviceInterfaceConstant.GetPeopleBirthday);
            aNative.setRetVal(Type.INT); // 指定返回参数的类型
            Pointer rsP = new Pointer(MemoryBlockFactory.createMemoryBlock(16));
            Pointer lengthP = new Pointer(MemoryBlockFactory.createMemoryBlock(4 * 10));
            aNative.setParameter(0, rsP);
            aNative.setParameter(1, lengthP);
            aNative.invoke();
            int rtv = Integer.parseInt(aNative.getRetVal());
            if (rtv == FunctionResultEnum.SUCCESS.getCode()) {
                int len = lengthP.getAsInt(0);
                byte[] resultBytes = new byte[len];
                resultBytes = rsP.getMemory();
                try {
                    name = new String(resultBytes, "gb2312");
                } catch (UnsupportedEncodingException ex) {
                    logger.error("编码结果时异常", ex);
                }
            }
            rsP.dispose();
            lengthP.dispose();
        } catch (IllegalAccessException e) {
            logger.error("本地方法调用时出错", e);
        } catch (NativeException e) {
            logger.error("加载动态库时出错", e);
        }
        return name;
    }

    public String getPeopleAddress() {
        JNative aNative = null;
        String name = null;
        try {
            aNative = new JNative("Termb.dll", DeviceInterfaceConstant.GetPeopleAddress);
            aNative.setRetVal(Type.INT); // 指定返回参数的类型
            Pointer rsP = new Pointer(MemoryBlockFactory.createMemoryBlock(70));
            Pointer lengthP = new Pointer(MemoryBlockFactory.createMemoryBlock(4 * 10));
            aNative.setParameter(0, rsP);
            aNative.setParameter(1, lengthP);
            aNative.invoke();
            int rtv = Integer.parseInt(aNative.getRetVal());
            if (rtv == FunctionResultEnum.SUCCESS.getCode()) {
                int len = lengthP.getAsInt(0);
                byte[] resultBytes = new byte[len];
                resultBytes = rsP.getMemory();
                try {
                    name = new String(resultBytes, "gb2312");
                } catch (UnsupportedEncodingException ex) {
                    logger.error("编码结果时异常", ex);
                }
            }
            rsP.dispose();
            lengthP.dispose();
        } catch (IllegalAccessException e) {
            logger.error("本地方法调用时出错", e);
        } catch (NativeException e) {
            logger.error("加载动态库时出错", e);
        }
        return name;
    }

    public String getPeopleIDCode() {
        JNative aNative = null;
        String name = null;
        try {
            aNative = new JNative("Termb.dll", DeviceInterfaceConstant.GetPeopleIDCode);
            aNative.setRetVal(Type.INT); // 指定返回参数的类型
            Pointer rsP = new Pointer(MemoryBlockFactory.createMemoryBlock(36));
            Pointer lengthP = new Pointer(MemoryBlockFactory.createMemoryBlock(4 * 10));
            aNative.setParameter(0, rsP);
            aNative.setParameter(1, lengthP);
            aNative.invoke();
            int rtv = Integer.parseInt(aNative.getRetVal());
            if (rtv == FunctionResultEnum.SUCCESS.getCode()) {
                int len = lengthP.getAsInt(0);
                byte[] resultBytes = new byte[len];
                resultBytes = rsP.getMemory();
                try {
                    name = new String(resultBytes, "gb2312");
                } catch (UnsupportedEncodingException ex) {
                    logger.error("编码结果时异常", ex);
                }
            }
            rsP.dispose();
            lengthP.dispose();
        } catch (IllegalAccessException e) {
            logger.error("本地方法调用时出错", e);
        } catch (NativeException e) {
            logger.error("加载动态库时出错", e);
        }
        return name;
    }

    public String getDepartment() {
        JNative aNative = null;
        String name = null;
        try {
            aNative = new JNative("Termb.dll", DeviceInterfaceConstant.GetDepartment);
            aNative.setRetVal(Type.INT); // 指定返回参数的类型
            Pointer rsP = new Pointer(MemoryBlockFactory.createMemoryBlock(30));
            Pointer lengthP = new Pointer(MemoryBlockFactory.createMemoryBlock(4 * 10));
            aNative.setParameter(0, rsP);
            aNative.setParameter(1, lengthP);
            aNative.invoke();
            int rtv = Integer.parseInt(aNative.getRetVal());
            if (rtv == FunctionResultEnum.SUCCESS.getCode()) {
                int len = lengthP.getAsInt(0);
                byte[] resultBytes = new byte[len];
                resultBytes = rsP.getMemory();
                try {
                    name = new String(resultBytes, "gb2312");
                } catch (UnsupportedEncodingException ex) {
                    logger.error("编码结果时异常", ex);
                }
            }
            rsP.dispose();
            lengthP.dispose();
        } catch (IllegalAccessException e) {
            logger.error("本地方法调用时出错", e);
        } catch (NativeException e) {
            logger.error("加载动态库时出错", e);
        }
        return name;
    }

    public String getStartDate() {
        JNative aNative = null;
        String name = null;
        try {
            aNative = new JNative("Termb.dll", DeviceInterfaceConstant.GetStartDate);
            aNative.setRetVal(Type.INT); // 指定返回参数的类型
            Pointer rsP = new Pointer(MemoryBlockFactory.createMemoryBlock(16));
            Pointer lengthP = new Pointer(MemoryBlockFactory.createMemoryBlock(4 * 10));
            aNative.setParameter(0, rsP);
            aNative.setParameter(1, lengthP);
            aNative.invoke();
            int rtv = Integer.parseInt(aNative.getRetVal());
            if (rtv == FunctionResultEnum.SUCCESS.getCode()) {
                int len = lengthP.getAsInt(0);
                byte[] resultBytes = new byte[len];
                resultBytes = rsP.getMemory();
                try {
                    name = new String(resultBytes, "gb2312");
                } catch (UnsupportedEncodingException ex) {
                    logger.error("编码结果时异常", ex);
                }
            }
            rsP.dispose();
            lengthP.dispose();
        } catch (IllegalAccessException e) {
            logger.error("本地方法调用时出错", e);
        } catch (NativeException e) {
            logger.error("加载动态库时出错", e);
        }
        return name;
    }

    public String getEndDate() {
        JNative aNative = null;
        String name = null;
        try {
            aNative = new JNative("Termb.dll", DeviceInterfaceConstant.GetEndDate);
            aNative.setRetVal(Type.INT); // 指定返回参数的类型
            Pointer rsP = new Pointer(MemoryBlockFactory.createMemoryBlock(16));
            Pointer lengthP = new Pointer(MemoryBlockFactory.createMemoryBlock(4 * 10));
            aNative.setParameter(0, rsP);
            aNative.setParameter(1, lengthP);
            aNative.invoke();
            int rtv = Integer.parseInt(aNative.getRetVal());
            if (rtv == FunctionResultEnum.SUCCESS.getCode()) {
                int len = lengthP.getAsInt(0);
                byte[] resultBytes = new byte[len];
                resultBytes = rsP.getMemory();
                try {
                    name = new String(resultBytes, "gb2312");
                } catch (UnsupportedEncodingException ex) {
                    logger.error("编码结果时异常", ex);
                }
            }
            rsP.dispose();
            lengthP.dispose();
        } catch (IllegalAccessException e) {
            logger.error("本地方法调用时出错", e);
        } catch (NativeException e) {
            logger.error("加载动态库时出错", e);
        }
        return name;
    }

    public String getBMPData() {
        JNative aNative = null;
        String name = null;
        try {
            aNative = new JNative("Termb.dll", DeviceInterfaceConstant.GetBMPData);
            aNative.setRetVal(Type.INT); // 指定返回参数的类型
            Pointer rsP = new Pointer(MemoryBlockFactory.createMemoryBlock(38862));
            Pointer lengthP = new Pointer(MemoryBlockFactory.createMemoryBlock(4 * 10));
            aNative.setParameter(0, rsP);
            aNative.setParameter(1, lengthP);
            aNative.invoke();
            int rtv = Integer.parseInt(aNative.getRetVal());
            if (rtv == FunctionResultEnum.SUCCESS.getCode()) {
                int len = lengthP.getAsInt(0);
                byte[] resultBytes = new byte[len];
                resultBytes = rsP.getMemory();
                try {
                    name = new String(resultBytes, "gb2312");
                } catch (UnsupportedEncodingException ex) {
                    logger.error("编码结果时异常", ex);
                }
            }
            rsP.dispose();
            lengthP.dispose();
        } catch (IllegalAccessException e) {
            logger.error("本地方法调用时出错", e);
        } catch (NativeException e) {
            logger.error("加载动态库时出错", e);
        }
        return name;
    }

    public String getFPDate() {
        JNative aNative = null;
        String name = null;
        try {
            aNative = new JNative("Termb.dll", DeviceInterfaceConstant.GetFPDate);
            aNative.setRetVal(Type.INT); // 指定返回参数的类型
            Pointer rsP = new Pointer(MemoryBlockFactory.createMemoryBlock(1024));
            Pointer lengthP = new Pointer(MemoryBlockFactory.createMemoryBlock(4 * 10));
            aNative.setParameter(0, rsP);
            aNative.setParameter(1, lengthP);
            aNative.invoke();
            int rtv = Integer.parseInt(aNative.getRetVal());
            if (rtv == FunctionResultEnum.SUCCESS.getCode()) {
                int len = lengthP.getAsInt(0);
                byte[] resultBytes = new byte[len];
                resultBytes = rsP.getMemory();
                try {
                    name = new String(resultBytes, "gb2312");
                } catch (UnsupportedEncodingException ex) {
                    logger.error("编码结果时异常", ex);
                }
            }
            rsP.dispose();
            lengthP.dispose();
        } catch (IllegalAccessException e) {
            logger.error("本地方法调用时出错", e);
        } catch (NativeException e) {
            logger.error("加载动态库时出错", e);
        }
        return name;
    }

    public String getPeopleChineseName() {
        JNative aNative = null;
        String name = null;
        try {
            aNative = new JNative("Termb.dll", DeviceInterfaceConstant.GetPeopleChineseName);
            aNative.setRetVal(Type.INT); // 指定返回参数的类型
            Pointer rsP = new Pointer(MemoryBlockFactory.createMemoryBlock(120));
            Pointer lengthP = new Pointer(MemoryBlockFactory.createMemoryBlock(4 * 10));
            aNative.setParameter(0, rsP);
            aNative.setParameter(1, lengthP);
            aNative.invoke();
            int rtv = Integer.parseInt(aNative.getRetVal());
            if (rtv == FunctionResultEnum.SUCCESS.getCode()) {
                int len = lengthP.getAsInt(0);
                byte[] resultBytes = new byte[len];
                resultBytes = rsP.getMemory();
                try {
                    name = new String(resultBytes, "gb2312");
                } catch (UnsupportedEncodingException ex) {
                    logger.error("编码结果时异常", ex);
                }
            }
            rsP.dispose();
            lengthP.dispose();
        } catch (IllegalAccessException e) {
            logger.error("本地方法调用时出错", e);
        } catch (NativeException e) {
            logger.error("加载动态库时出错", e);
        }
        return name;
    }

    //通行证号码
    public String getPassCheckID() {
        JNative aNative = null;
        String name = null;
        try {
            aNative = new JNative("Termb.dll", DeviceInterfaceConstant.GetPassCheckID);
            aNative.setRetVal(Type.INT); // 指定返回参数的类型
            Pointer rsP = new Pointer(MemoryBlockFactory.createMemoryBlock(4 * 30));
            Pointer lengthP = new Pointer(MemoryBlockFactory.createMemoryBlock(4 * 10));
            aNative.setParameter(0, rsP);
            aNative.setParameter(1, lengthP);
            aNative.invoke();
            int rtv = Integer.parseInt(aNative.getRetVal());
            if (rtv == FunctionResultEnum.SUCCESS.getCode()) {
                int len = lengthP.getAsInt(0);
                byte[] resultBytes = new byte[len];
                resultBytes = rsP.getMemory();
                try {
                    name = new String(resultBytes, "gb2312");
                } catch (UnsupportedEncodingException ex) {
                    logger.error("编码结果时异常", ex);
                }
            }
            rsP.dispose();
            lengthP.dispose();
        } catch (IllegalAccessException e) {
            logger.error("本地方法调用时出错", e);
        } catch (NativeException e) {
            logger.error("加载动态库时出错", e);
        }
        return name;
    }

    //签发次数
    public String getIssuesNum() {
        JNative aNative = null;
        String name = null;
        try {
            aNative = new JNative("Termb.dll", DeviceInterfaceConstant.GetIssuesNum);
            aNative.setRetVal(Type.INT); // 指定返回参数的类型
            Pointer rsP = new Pointer(MemoryBlockFactory.createMemoryBlock(4 * 30));
            Pointer lengthP = new Pointer(MemoryBlockFactory.createMemoryBlock(4 * 10));
            aNative.setParameter(0, rsP);
            aNative.setParameter(1, lengthP);
            aNative.invoke();
            int rtv = Integer.parseInt(aNative.getRetVal());
            if (rtv == FunctionResultEnum.SUCCESS.getCode()) {
                int len = lengthP.getAsInt(0);
                byte[] resultBytes = new byte[len];
                resultBytes = rsP.getMemory();
                try {
                    name = new String(resultBytes, "gb2312");
                } catch (UnsupportedEncodingException ex) {
                    logger.error("编码结果时异常", ex);
                }
            }
            rsP.dispose();
            lengthP.dispose();
        } catch (IllegalAccessException e) {
            logger.error("本地方法调用时出错", e);
        } catch (NativeException e) {
            logger.error("加载动态库时出错", e);
        }
        return name;
    }

    //外国人证件版本
    public String getPeopleCertVersion() {
        JNative aNative = null;
        String name = null;
        try {
            aNative = new JNative("Termb.dll", DeviceInterfaceConstant.GetPeopleCertVersion);
            aNative.setRetVal(Type.INT); // 指定返回参数的类型
            Pointer rsP = new Pointer(MemoryBlockFactory.createMemoryBlock(4 * 30));
            Pointer lengthP = new Pointer(MemoryBlockFactory.createMemoryBlock(4 * 10));
            aNative.setParameter(0, rsP);
            aNative.setParameter(1, lengthP);
            aNative.invoke();
            int rtv = Integer.parseInt(aNative.getRetVal());
            if (rtv == FunctionResultEnum.SUCCESS.getCode()) {
                int len = lengthP.getAsInt(0);
                byte[] resultBytes = new byte[len];
                resultBytes = rsP.getMemory();
                try {
                    name = new String(resultBytes, "gb2312");
                } catch (UnsupportedEncodingException ex) {
                    logger.error("编码结果时异常", ex);
                }
            }
            rsP.dispose();
            lengthP.dispose();
        } catch (IllegalAccessException e) {
            logger.error("本地方法调用时出错", e);
        } catch (NativeException e) {
            logger.error("加载动态库时出错", e);
        }
        return name;
    }

    @Override
    public void close() throws IOException {

    }
}
